package com.example.sams.service.impl;

import com.example.sams.domain.enums.UserRole;
import com.example.sams.domain.po.Admins;
import com.example.sams.domain.po.Students;
import com.example.sams.domain.po.Teachers;
import com.example.sams.domain.po.Users;
import com.example.sams.domain.request.LoginRequest;
import com.example.sams.domain.vo.*;
import com.example.sams.mapper.*;
import com.example.sams.mapper.UsersMapper;
import com.example.sams.service.IUsersService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.sams.utils.JwtUtil;
import com.example.sams.utils.ResultUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.Map;

/**
 * <p>
 * 用户表 服务实现类
 * </p>
 *
 * @author jinghong
 * @since 2025-11-04
 */
@Service
public class UsersServiceImpl extends ServiceImpl<UsersMapper, Users> implements IUsersService {
    // 注入UserMapper：通过它调用数据库查询方法
    @Autowired
    private UsersMapper userMapper;
    @Autowired
    private StudentsMapper studentMapper;

    @Autowired
    private TeachersMapper teacherMapper;

    @Autowired
    private AdminsMapper adminMapper;

    // 注入JwtUtil：用于生成登录令牌（token）
    @Autowired
    private JwtUtil jwtUtil;

    @Override
    public ResultUtil login(LoginRequest loginRequest) {
        // 1. 获取前端输入的登录ID和密码
        String username = loginRequest.getUsername();
        String password = loginRequest.getPassword();
        UserRole userRole = loginRequest.getRole();

        // 2. 非空校验：如果登录ID或密码为空，直接返回失败
        if (username == null || username.trim().isEmpty() || password == null || password.trim().isEmpty()) {
            return ResultUtil.error("登录ID或密码不能为空");
        }

        // 3. 调用Mapper层查询用户：根据loginId查数据库
        Users user = userMapper.selectByLoginId(username);

        // 4. 验证用户是否存在：如果查不到用户，返回“登录ID不存在”
        if (user == null) {
            return ResultUtil.error("登录ID不存在");
        }

        if (user.getRole() != userRole){
            return ResultUtil.error("角色错误,请重新选择正确登录角色");
        }

        // 5. 验证密码：将前端输入的密码加密后，和数据库中的加密密码比对
        String encryptedPassword = md5(password); // 前端密码加密
        if (!encryptedPassword.equals(user.getPassword())) { // 和数据库密码比对
            return ResultUtil.error("密码错误");
        }


        // 【修改点】生成令牌时，传入loginId和user.getUserRole()（角色）
        // 原代码：String token = jwtUtil.generateToken(loginId);
        String token = jwtUtil.generateToken(user.getId(), user.getRole());

        BaseUserVO userInfo = buildUserInfo(user);

        LoginVO responseVO =  LoginVO.builder()
                .token(token)
                .user(userInfo)
                .build();


        // 组装返回数据（前端需要token和角色信息）
        return ResultUtil.success(responseVO);
    }


    private BaseUserVO buildUserInfo(Users user) {
        switch (user.getRole()) {
            case student:
                return buildStudentInfo(user);
            case teacher:
                return buildTeacherInfo(user);
            case admin:
                return buildAdminInfo(user);
            default:
                return null;
        }
    }

        private StudentUserVO buildStudentInfo(Users user) {
        // 根据学号查询学生详细信息
        Students student = studentMapper.selectByUserId(user.getId());

        if (student != null) {
            return StudentUserVO.builder()
                    .id(user.getId())
                    .name(user.getName())
                    .studentNo(student.getStudentNo())
                    .college(user.getCollege())
                    .major(student.getMajor())
                    .clazz(student.getClazz())
                    .build();
        }
        return null;
    }

    private TeacherUserVO buildTeacherInfo(Users user) {
        // 根据工号查询教师详细信息
        Teachers teacher = teacherMapper.selectByUserId(user.getId());

        if (teacher != null) {
            return TeacherUserVO.builder()
                    .id(user.getId())
                    .name(user.getName())
                    .account(teacher.getAccount())
                    .college(user.getCollege())
                    .title(teacher.getTitle())
                    .build();
        }
        return null;
    }

    private AdminUserVO buildAdminInfo(Users user) {
        // 根据账号查询管理员详细信息
        Admins admin = adminMapper.selectByUserId(user.getId());

        if (admin != null) {
            return AdminUserVO.builder()
                    .id(user.getId())
                    .name(user.getName())
                    .account(admin.getAccount())
                    .build();
        }
        return null;
    }




    @Override
    public ResultUtil changePassword(String userId, String oldPassword, String newPassword) {
        // 1. 参数验证
        if (oldPassword == null || oldPassword.trim().isEmpty()) {
            return ResultUtil.error("旧密码不能为空");
        }
        if (newPassword == null || newPassword.trim().isEmpty()) {
            return ResultUtil.error("新密码不能为空");
        }

        // 2. 查询用户
        Users user = this.getById(userId);
        if (user == null) {
            return ResultUtil.error("用户不存在");
        }

        // 3. 验证旧密码
        String encryptedOldPassword = md5(oldPassword);
        if (!encryptedOldPassword.equals(user.getPassword())) {
            return ResultUtil.error("旧密码错误");
        }

        // 4. 更新密码
        String encryptedNewPassword = md5(newPassword);
        user.setPassword(encryptedNewPassword);
        boolean updated = this.updateById(user);

        if (updated) {
            Map<String, Object> data = new HashMap<>();
            data.put("success", true);
            return ResultUtil.success("密码修改成功", data);
        } else {
            return ResultUtil.error("密码修改失败");
        }
    }

    // 辅助方法：将明文密码转为MD5加密字符串（和数据库存储的密码格式一致）
    private String md5(String password) {
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            byte[] bytes = md.digest(password.getBytes()); // 加密
            // 转成16进制字符串
            StringBuilder sb = new StringBuilder();
            for (byte b : bytes) {
                String hex = Integer.toHexString(b & 0xFF);
                if (hex.length() == 1) {
                    sb.append("0"); // 补0，确保32位长度
                }
                sb.append(hex);
            }
            return sb.toString();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
            return ""; // 加密失败返回空（实际项目可抛异常）
        }
    }


}
